home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-01
/
smailsrc.zip
/
UUPC.ZIP
/
ULIB.C
< prev
next >
Wrap
Text File
|
1990-04-21
|
10KB
|
452 lines
/*
For best results in visual layout while viewing this file, set
tab stops to every 8 columns.
*/
/*
ibmpc/ulib.c
DCP system-dependent library
Services provided by ulib.c:
- login
- UNIX commands simulation
- serial I/O
- rnews
*/
/*
* Modified by Stephen C. Trier (sct@po.CWRU.Edu)
* January - April, 1990
*
* Added support for external rmail and rnews commands.
* External rmail is mandatory; external rnews is not.
*
* DTR now stays low long enough to make smart modem hang
* up. This was needed for multiple-host support.
*/
#include <stdio.h>
#include <string.h>
#include <process.h>
#include <fcntl.h>
#include "dcp.h"
extern int rmsg();
extern void wmsg();
/*
login - login handler
*/
/* Currently a dumb login handler for PC in slave mode. */
char login(void)
{
char line[132];
for ( ; ; ) {
msgtime = 9999; /* make it very long */
while (rmsg(line, 0) == -1); /* wait for a <CR> or <NL> */
msgtime = 2 * MSGTIME;
wmsg("Login:", 0);
if (rmsg(line, 0) == -1)
continue;
printmsg(0, "login: login=%s", line);
wmsg("Password:", 0);
if (rmsg(line, 0) == -1)
continue;
printmsg(14, "login: password=%s", line);
if (equal(line, "uucp"))
break;
}
printmsg(14, "login: logged in");
return 'I';
} /*login*/
/*
notimp - "perform" Unix commands which aren't implemented
*/
static int notimp(argc, argv)
int argc;
char *argv[];
{
int i = 1;
printmsg(0, "shell: command '%s' not implemented", *argv);
while (i < argc)
printmsg(6, "shell: argv[%d]=\"%s\"", i++, *argv++);
return 0;
} /*notimp*/
/*
shell - simulate a Unix command
Only the 'rmail' and 'rnews' command are currently supported.
*/
void shell(command, inname, outname, errname)
char *command;
char *inname, *outname, *errname;
{
extern int rmail(), rnews();
char *argv[50];
int argc;
int (*proto)();
argc = getargs(command, argv);
if (debuglevel >= 6) {
char **argvp = argv;
int i = 0;
while (i < argc)
printmsg(6, "shell: argv[%d]=\"%s\"", i++, *argvp++);
}
if (equal(argv[0], "rmail"))
proto = rmail;
else if (equal(argv[0], "rnews"))
proto = rnews;
else
proto = notimp;
if (*inname != '\0') {
char localname[64];
importpath(localname, inname);
if (freopen(localname, "rb", stdin) == nil(FILE)) {
extern int errno;
printmsg(0, "shell: couldn't open %s (%s), errno=%d.",
inname, localname, errno);
}
}
(*proto)(argc, argv);
freopen("con", "r", stdin);
} /*shell*/
/* IBM-PC I/O routines */
/* "DCP" a uucp clone. Copyright Richard H. Lamb 1985,1986,1987 */
/*************** BASIC I/O ***************************/
/* Saltzers serial package (aka Info-IBMPC COM_PKG2):
* Some notes: When packets are flying in both directions, there seems to
* be some interrupt handling problems as far as receiving. Checksum errors
* may therefore occur often even though we recover from them. This is
* especially true with sliding windows. Errors are very few in the VMS
* version. RH Lamb
*/
#include "comm\comm.h"
#define STOPBIT 1
#define LINELOG "LineData.Log" /* log serial line data here */
static int log_handle;
static FILE *log_stream;
/*
openline - open the serial port for I/O
*/
int openline(name, baud)
char *name, *baud;
{
int value;
printmsg(15, "openline: %s, %s", name, baud);
sscanf(name, "COM%d", &value);
select_port(value);
save_com();
install_com();
open_com(atoi(baud), 'D', 'N', STOPBIT, 'D');
dtr_on();
/* log serial line data only if log file already exists */
log_handle = open(LINELOG, O_WRONLY | O_TRUNC | O_BINARY);
if (log_handle != -1) {
printmsg(15, "logging serial line data to %s", LINELOG);
log_stream = fdopen(log_handle, "wb");
}
return 0;
} /*openline*/
/*
sread - read from the serial port
*/
/* Non-blocking read essential to "g" protocol.
See "dcpgpkt.c" for description.
This all changes in a multi-tasking system. Requests for
I/O should get queued and an event flag given. Then the
requesting process (e.g. gmachine()) waits for the event
flag to fire processing either a read or a write.
Could be implemented on VAX/VMS or DG but not MS-DOS. */
int sread(buffer, wanted, timeout)
char *buffer;
int wanted, timeout;
{
long start;
start = time(nil(long));
for ( ; ; ) {
int pending;
pending = r_count_pending();
printmsg(20, "sread: pending=%d, wanted=%d", pending, wanted);
if (pending >= wanted) { /* got enough in the buffer? */
int i;
for (i = 0; i < wanted; i++)
*buffer++ = receive_com();
if (log_handle != -1) {
buffer -= wanted;
for (i = 0; i < wanted; i++) {
fputc(0x01, log_stream); /* 1 for writes */
fputc(*buffer++, log_stream);
}
}
return pending;
} else {
int elapsed;
elapsed = time(nil(long)) - start;
if (elapsed >= timeout)
return pending;
}
}
} /*sread*/
/*
swrite - write to the serial port
*/
int swrite(data, len)
char *data;
int len;
{
int i;
for (i = 0; i < len; i++)
send_com(*data++);
if (log_handle != -1) {
data -= len;
for (i = 0; i < len; i++) {
fputc(0x02, log_stream); /* 2 for writes */
fputc(*data++, log_stream);
}
}
return len;
} /*swrite*/
/*
ssendbrk - send a break signal out the serial port
*/
void ssendbrk(duration)
int duration;
{
printmsg(12, "ssendbrk: %d", duration);
break_com();
} /*ssendbrk*/
/*
closeline - close the serial port down
*/
void closeline(void)
{
int far *stats;
dtr_off();
close_com();
restore_com();
sleep(3); /* Make sure modem hangs up [SCT] */
if (log_handle != -1) { /* close serial line log file */
fclose(log_stream);
close(log_handle);
};
stats = com_errors();
printmsg(3, "\nBuffer overflows: %d", stats[COM_EOVFLOW]);
printmsg(3, "Receive overruns: %d", stats[COM_EOVRUN]);
printmsg(3, "Break chars: %d", stats[COM_EBREAK]);
printmsg(3, "Framing errors: %d", stats[COM_EFRAME]);
printmsg(3, "Parity errors: %d", stats[COM_EPARITY]);
printmsg(3, "Transmit errors: %d", stats[COM_EXMIT]);
printmsg(3, "DSR errors: %d", stats[COM_EDSR]);
printmsg(3, "CTS errors: %d\n", stats[COM_ECTS]);
} /*closeline*/
#ifndef __TURBOC__
/*
sleep() - wait n seconds
Simply delay until n seconds have passed.
*/
void sleep(interval)
int interval;
{
long start;
start = time(nil(long));
while ((time(nil(long)) - start) < interval);
} /*sleep*/
#endif /*__TURBOC__*/
/*
SIOSpeed - re-specify the speed of an opened serial port
*/
void SIOSpeed(baud)
char *baud;
{
dtr_off();
close_com();
open_com(atoi(baud), 'D', 'N', STOPBIT, 'D');
dtr_on();
} /*SIOSpeed*/
/*
* rnews - receive incoming news
*
* I added provisions for a stand-alone rnews, with fallback to the normal
* UUPC rnews. I do not receive news, so I have not been able to test this
* feature. I hope it works. If you try it, please send me a note saying
* how it works. -- Stephen Trier (sct@po.cwru.edu)
*
* rnews uses a static variable to tell it if any previous spawn of rnews
* failed. If it did, it will use the internal rnews. This keeps the
* routine from trying to spawn rnews for every single incoming news article,
* unless there is an rnews there to receive them. -- Stephen Trier
*/
int rnews(int argc, char *argv[]) /* SCT */
{
static int temp = 0;
argv[argc] = NULL;
if (temp != -1)
temp = spawnvp(P_WAIT, "rnews", argv);
switch (temp) {
case 0:
break;
case -1:
printmsg(2, "Can't find rnews in path. Using internal rnews.");
temp = old_rnews(argc, argv);
break;
default:
printmsg(1, "rnews returns %d", temp);
break;
}
return temp;
}
/*
* This is the original UUPC rnews, modified so that it handles
* binary data correctly. -- SCT
*/
int old_rnews(argc, argv)
int argc;
char *argv[];
{
static int count = 1;
char filename[132], format[128], buf[BUFSIZ];
#ifndef OLD_RNEWS
size_t charsread;
#endif
FILE *f;
long now = time(nil(long));
mkfilename(format, newsdir, "%08.8lX.%03.3d"); /* make pattern first */
sprintf(filename, format, now, count++); /* build real file name */
printmsg(6, "rnews: putting incoming news into %s", filename);
if ((f = FOPEN(filename, "w", BINARY)) == nil(FILE)) {
printmsg(0, "rnews: can't open %s (%d)", filename, errno);
return -1;
}
#ifdef OLD_RNEWS
while (fgets(buf, BUFSIZ, stdin) != nil(char))
fputs(buf, f);
#else
while ((charsread = fread(buf, (size_t) 1, (size_t) BUFSIZ, stdin)) != 0)
fwrite(buf, (size_t) 1, charsread, f);
#endif
fclose(f);
return 0;
} /*rnews*/
/*
* rmail - Call external rmail program (SCT)
*/
#include <errno.h>
int rmail(int argc, char *argv[])
{
int temp;
argv[argc] = NULL;
temp = spawnvp(P_WAIT, "rmail", argv);
switch (temp) {
case 0:
break;
case -1:
printmsg(0, "Error while forking rmail: %s", sys_errlist[errno]);
break;
default:
printmsg(1, "rmail returns %d", temp);
break;
}
return temp;
}